package com.jy.wms.service;

import com.joyi.gate.comm.SessionInfo;
import com.joyi.gate.safety.vo.UserInfo;
import com.jy.wms.common.UUIDUtils;
import com.jy.wms.common.annotions.BaseServiceDescribe;
import com.jy.wms.common.base.*;
import com.jy.wms.dao.WmsEstimatedArrivalOrderDetailedMapper;
import com.jy.wms.dao.WmsEstimatedArrivalOrderMapper;
import com.jy.wms.pojo.*;
import net.sf.json.JSONObject;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.util.PoiPublicUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpSession;
import java.io.File;
import java.math.BigDecimal;
import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.*;

/**
* @ClassName: WmsEstimatedArrivalOrderDetailedService.java
* @Description: TODO(这里用一句话描述这个类的作用)
* @Author Liyi
* @Date Wed Sep 27 09:49:11 CST 2017
*/

@Service
public class WmsEstimatedArrivalOrderDetailedService extends BaseService<WmsEstimatedArrivalOrderDetailedMapper,WmsEstimatedArrivalOrderDetailed> {

    @Autowired
    private WmsEstimatedArrivalOrderMapper wmsEstimatedArrivalOrderMapper;

 /**
 * 插入一条记录
 * @param entity 实体对象
 * @return int
 */
public Integer baseInsert(WmsEstimatedArrivalOrderDetailed entity ){
     return dao.baseInsert( entity );
}

/**
* 插入一条记录（匹配有值的字段）
* @param entity 实体对象
* @return int
*/
@BaseServiceDescribe(moduleName = "预期到货通知单明细",btnName = "新增预期到货通知单明细")
public Integer baseInsertSelective(WmsEstimatedArrivalOrderDetailed entity )throws SucessException,ServiceException {
        entity.setId(UUIDUtils.uuid());
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        entity.setScrq(formatter.format(new Date(Integer.valueOf(entity.getScrq()))));
        entity.setSxrq(formatter.format(new Date(Integer.valueOf(entity.getSxrq()))));
        if(entity.getBz() == null){
            entity.setBz("");
        }
        Integer addCount = dao.baseInsertSelective( entity );
        if(addCount>0){
            entity = dao.selectById(entity.getId());
            throw new SucessException("新增预期到货通知单明细成功");
        }else{
            throw new ServiceException("新增预期到货通知单明细失败，未插入数据库");
        }
}

    /**
     *调整确认收货
     * @param ssyqdid 预期到货通知单ID
     * @return int
     */
    @BaseServiceDescribe(moduleName = "ASN码盘",btnName = "调整确认收货")
    public WmsEstimatedArrivalOrderDetailed ConfirmationASN(String ssyqdid) throws ServiceException {
        try{
            return dao.ConfirmationASN(ssyqdid);
        }catch (Exception e){
            throw new ServiceException("查询ASN码盘信息失败",e);
        }
    }


/**
* 删除（根据主键ID删除）
* @param id 主键
* @return int
*/
public Integer baseDeleteByPrimaryKey(String id ){
     return dao.baseDeleteByPrimaryKey( id );
}

/**
* 删除（根据ID 批量删除）
* @param idList 主键ID列表
* @return int
*/
public Integer baseDeleteBathPrimaryKeys(List<String> idList ){
     return dao.baseDeleteBathPrimaryKeys( idList );
}

/**
* 分页查询
* @param entity 实体
* @return Page<WmsEstimatedArrivalOrderDetailed>
*/
public Page<WmsEstimatedArrivalOrderDetailed> baseSelectPage(WmsEstimatedArrivalOrderDetailed entity ){
    PageHelper.startPage(entity.getPage(),entity.getRows());
    return (Page<WmsEstimatedArrivalOrderDetailed>)dao.baseSelectPage( entity );
}

/**
* 查询（根据主键ID查询）
* @param id 主键ID
* @return WmsEstimatedArrivalOrderDetailed
*/
public WmsEstimatedArrivalOrderDetailed baseSelectByPrimaryKey(String id ){
     return dao.baseSelectByPrimaryKey( id );
}

/**
 * 查询（根据ssyqdid所属预期到货单ID查询）
 * @param ssyqdid 所属预期到货单ID
 * @return
 */
@BaseServiceDescribe(moduleName = "预期到货通知单明细",btnName = "根据预期到货通知单ID查询所属预期到货通知单明细")
public List<WmsEstimatedArrivalOrderDetailed> getBySsyqdid(String ssyqdid) throws ServiceException {
    try {
        return dao.getBySsyqdid(ssyqdid);
    } catch (Exception e) {
        e.printStackTrace();
        throw new ServiceException("根据预期到货通知单ID查询所属预期到货通知单明细");
    }
}

/**
 * 查询（根据主键ID查询）
 * @param ssyqdid 所属预期到货单ID
 * @return WmsEstimatedArrivalOrderDetailed
 */
public List<WmsEstimatedArrivalOrderDetailed> baseSelectBySsyqdid(String ssyqdid ){
    return dao.baseSelectBySsyqdid( ssyqdid );
}

/**
* 查询（根据ID 批量查询）
* @param idList 主键ID列表
* @return list
*/
public Integer baseSelectBathPrimaryKeys(List<WmsEstimatedArrivalOrderDetailed> idList ){
     return dao.baseSelectBathPrimaryKeys( idList );
}

/**
*修改 （匹配有值的字段）
* @param entity 主键ID列表
* @return int
*/
@BaseServiceDescribe(moduleName = "预期到货通知单明细",btnName = "修改预期到货通知单明细")
public Integer baseUpdateByPrimaryKeySelective(WmsEstimatedArrivalOrderDetailed entity )throws SucessException,ServiceException {
    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    entity.setScrq(formatter.format(new Date(Long.valueOf(entity.getScrq()))));
    if(entity.getSxrq() !=null && !entity.getSxrq().equals("")){
        entity.setSxrq(formatter.format(new Date(Long.valueOf(entity.getSxrq()))));
    }
    entity.setSsyqdid(entity.getId());
    if(entity.getBz() == null){
        entity.setBz("");
    }
    //计算箱单位数量
    String str = wmsEstimatedArrivalOrderMapper.getCountByZdw(entity.getZdwid());
    Integer count = str == null ? Integer.MAX_VALUE : Integer.valueOf(str);
    Double zsl = Double.valueOf(entity.getYqsl());
    StringBuffer yqxsl = new StringBuffer("");
    yqxsl.append((int)(zsl/count)+"箱");
    yqxsl.append((int)(zsl%count)+"件");
     Integer editCount = dao.baseUpdateByPrimaryKeySelective( entity );
     if(editCount>0){
         throw new SucessException("修改预期到货通知单明细成功");
     }else{
         throw new ServiceException("修改预期到货通知单明细失败,未插入数据库");
     }
}

/**
*修改（根据主键ID修改）
* @param entity 主键ID列表
* @return int
*/
public Integer baseUpdateByPrimaryKey(WmsEstimatedArrivalOrderDetailed entity ){
     return dao.baseUpdateByPrimaryKey( entity );
}
    /**
     *查询ASN码盘信息 （根据预期到货通知单ID查询）
     * @param ssyqdid 预期到货通知单ID
     * @return int
     */
    @BaseServiceDescribe(moduleName = "ASN码盘",btnName = "分页查询码盘信息")
    public Page<WmsEstimatedArrivalOrderDetailed> seachASNBySsyqdid(String ssyqdid, Integer Page, Integer Rows)throws Exception {
        try{
            PageHelper.startPage(Page,Rows);
            Page<WmsEstimatedArrivalOrderDetailed>list = (Page<WmsEstimatedArrivalOrderDetailed>) dao.seachASNBySsyqdid(ssyqdid);
            return list;
        }catch (Exception e){
            throw new ServiceException("查询ASN码盘信息失败",e);
        }

    }

    @BaseServiceDescribe(moduleName = "预期到货通知单明细",btnName = "删除预期到货通知单明细")
    public void delete(SetAndModifyModel setAndModifyModel)throws SucessException,ServiceException {
       Integer delCount = dao.delAsn(setAndModifyModel.getIds());
       if(delCount>0){
           throw new SucessException("选中明细"+setAndModifyModel.getIds().size()+"条，删除成功"+delCount+"条");
       }else{
           throw new ServiceException("删除预期到货通知单明细成功,未插入数据库");
       }
    }

    ///////////////////导入预期到货通知单///////////////////////////
    /**
     * 导入预期到货通知单
     * @param session
     * @param filepath
     * @throws Exception
     */
    @BaseServiceDescribe(moduleName = "导入预期到货通知单", btnName = "导入预期到货通知单")
    @Transactional
    public void importWmsEstimatedExcle(HttpSession session, String  filepath) throws Exception {
        ImportParams params = new ImportParams();
        params.setNeedSave(false);
        params.setTitleRows(0);
        params.setHeadRows(1);
        params.setDataHanlder(new WmsEstimatedImportHanlder());
      /*  JSONObject jb = JSONObject.fromObject(filepath);
        URL url = new URL((String) jb.get("filepath"));
        URLConnection conn = url.openConnection();
        List<Map<String, Object>> result = ExcelImportUtil.importExcel(
                //conn.getInputStream(),
                new File(PoiPublicUtil.getWebRootPath("import/入库单导入模板.xls")),
                Map.class, params);*/
        List<Map<String, Object>> result = ExcelImportUtil.importExcel(
                new File(filepath),
                Map.class, params);
        UserInfo userinfo = (UserInfo) session.getAttribute(SessionInfo.USER_INFO);
        List<SysHz> hz = (List<SysHz>) session.getAttribute(BaseSessionInfo.SessionConsignor);
        //仓库id
        String ckid = String.valueOf(userinfo.getUser().getOrgId().get(0));
        //货主id
        String hzid = null;
        if (hz.size() > 0) {
            hzid = hz.get(0).getHzid();
        }
        //asn单号
        Set<String> set= new HashSet();
        //必填项验证信息
        StringBuffer gf = new StringBuffer();
        for (int i = 0; i < result.size(); i++) {
            result.get(i).put("num", i + 2);
            set.add(String.valueOf(result.get(i).get("asnbh")));
            //必填项验证信息方法
            getBitian(result.get(i), gf);
        }
        if(gf != null && !"".equals(gf) && gf.length() > 0){
            throw new RuntimeException(gf.toString());
        }
        //表格去重
        removeDuplicate(result);
        //数据库去重
        removeDataDuplicate(set, hzid, ckid);
        WmsEstimatedArrivalOrderDetailed entity=null;
        WmsEstimatedArrivalOrder order=null;
        Map map=new HashMap();
        //添加数据
        for(String asnbh:set) {
            order = new WmsEstimatedArrivalOrder();
            String uuid=UUIDUtils.uuid();
            order.setId(uuid);
            String gysid=dao.getGysid("三生供应商", hzid, ckid);
            order.setGysid(gysid);
            order.setHzid(hzid);
            order.setCkid(ckid);
            order.setAsnbh(asnbh);
            map.put(asnbh,uuid);
            order.setAsnlx(dao.getAsnlx("调拨入库单", hzid, ckid));
            order.setZdr(userinfo.getUser().getName());
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            order.setZdr(userinfo.getUser().getName());
            order.setCjsj(sdf.format(new Date()));
            order.setYjdhsjjs(sdf.format(new Date()));
            order.setYjdhsjks(sdf.format(new Date()));
            order.setXgr(userinfo.getUser().getName());
            order.setXgsj(sdf.format(new Date()));
            order.setAsnzt("0");
            Integer j = dao.saveOrder(order);
            if (j > 0) {

            } else {
                throw new RuntimeException("导入预期到货通知单失败");
            }
        }
        for(int ii=0;ii<result.size();ii++){
            entity = new WmsEstimatedArrivalOrderDetailed();
            entity.setId(UUIDUtils.uuid());
            //获取asnbh的id
            String asnbhss= String.valueOf(result.get(ii).get("asnbh"));
            //获取map内的所有键（编号）
            Set sets=map.keySet();
            //判断键内是否包含此编号
            boolean contains = sets.contains(asnbhss);
            //返回true（说明map包含此asn编号）
            if(contains){
                //从map中获取对应的id
                String anbhs= String.valueOf(map.get(asnbhss));
                entity.setSsyqdid(anbhs);
            }
            entity.setHzid(hzid);
            entity.setCkid(ckid);
            String hpid= dao.getHpId(String.valueOf(result.get(ii).get("hpbh")), String.valueOf(result.get(ii).get("hpmc")), ckid);
            if(hpid!=null && !"".equals(hpid)){
                entity.setHpid(hpid);
            }else{
                throw new RuntimeException("第"+String.valueOf(result.get(ii).get("num"))+"行:货品编号:"+String.valueOf(result.get(ii).get("hpbh"))+"，货品名称:"+String.valueOf(result.get(ii).get("hpmc"))+"，此货品在数据库不存在");
            }
            entity.setYqsl(String.valueOf(result.get(ii).get("yqsl")));
            //查货品id 下的包装主单位类型的 金额 jesl
            WmsPackingDetailed detailed = dao.getJe(entity.getHpid());
            if(detailed!=null){
                BigDecimal jes = new BigDecimal(detailed.getJe());
                BigDecimal yqsls = new BigDecimal(entity.getYqsl());
                BigDecimal bd = jes.multiply(yqsls);
                //设置小数位数，第一个变量是小数位数，第二个变量是取舍方法(四舍五入)
                BigDecimal bds = bd.setScale(4, BigDecimal.ROUND_HALF_UP);
                entity.setJe(bds);
                entity.setZdwid(detailed.getId());
            }else {
                throw new RuntimeException("第"+String.valueOf(result.get(ii).get("num"))+"行:货品编号:"+String.valueOf(result.get(ii).get("hpbh"))+"，货品名称:"+String.valueOf(result.get(ii).get("hpmc"))+"，此货品下的包装不存在");
            }
            //更改规格
            if(result.get(ii).get("gg")!=null && !"".equals(result.get(ii).get("gg"))){
                dao.getUpdatehp(String.valueOf(result.get(ii).get("gg")), entity.getHpid());
            }
            entity.setHppc(String.valueOf(result.get(ii).get("hppc")));
            entity.setScrq(String.valueOf(result.get(ii).get("scrq")));
            entity.setSxrq(String.valueOf(result.get(ii).get("sxrq")));
            entity.setBz(String.valueOf(result.get(ii).get("bz")));
            WmsEstimatedArrivalOrderDetailed wsEstimatedArrivalOrderDetailed = dao.getXzdw(entity.getHpid(), hzid, ckid);
            if (wsEstimatedArrivalOrderDetailed != null) {
                if (!"0".equals(entity.getYqsl()) && !"".equals(entity.getYqsl()) && entity.getYqsl() != null) {
                    if (!"0".equals(wsEstimatedArrivalOrderDetailed.getZdwsl()) && !"".equals(wsEstimatedArrivalOrderDetailed.getZdwsl())) {
                        //箱单位整数
                        Integer xdwzs = Integer.parseInt(entity.getYqsl()) / Integer.parseInt(wsEstimatedArrivalOrderDetailed.getZdwsl());
                        //箱单位余数
                        Integer xdwys = Integer.parseInt(entity.getYqsl()) % Integer.parseInt(wsEstimatedArrivalOrderDetailed.getZdwsl());
                        String yqxdwsl = xdwzs + "箱" + xdwys + "件";
                        //箱件总数(xxx箱xx件)
                        entity.setYqxsl(yqxdwsl);
                    } else {
                        entity.setYqxsl("0");
                    }
                }
                //保存明细
                Integer k = dao.saveDetailed(entity);
                if(k<=0){
                    throw new RuntimeException("导入预期到货通知单明细失败");
                }
            }else {
                throw new RuntimeException("第"+String.valueOf(result.get(ii).get("num"))+"行:货品编号:"+String.valueOf(result.get(ii).get("hpbh"))+"，货品名称:"+String.valueOf(result.get(ii).get("hpmc"))+"，此货品下的箱包装不存在");
            }
        }

    }

    /**
     * 表格内部去重
     * @param lis
     * @throws Exception
     */
    @Transactional
    public void removeDuplicate(List<Map<String, Object>> lis) throws Exception {
        //报表内不允许存在相同ASN单据号的情况
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < lis.size() - 1; i++) {
            for (int j = i + 1; j < lis.size(); j++) {
                if (lis.get(j).get("asnbh").equals(lis.get(i).get("asnbh"))&& lis.get(j).get("hpbh").equals(lis.get(i).get("hpbh")) && lis.get(j).get("hpmc").equals(lis.get(i).get("hpmc")) && lis.get(j).get("hppc").equals(lis.get(i).get("hppc"))) {
                    sb.append("第" + lis.get(j).get("num") + "行，调拨单单号:" + lis.get(j).get("asnbh").toString()+ ",物料编码:"+lis.get(j).get("hpbh").toString()+",物料名称:"+lis.get(j).get("hpmc").toString()+",");
                    lis.remove(j);
                    j--;
                }
            }
        }
        if (sb != null && !"".equals(sb) && sb.length() > 0) {
            throw new RuntimeException("表格中" + sb + "相同调拨单单号下货品信息重复，导入失败");
        }

    }

    /**
     * 数据库去重
     *
     * @param  set
     * @param hzid
     * @param ckid
     * @throws ServiceException
     */
    @Transactional
    public void removeDataDuplicate(Set<String> set, String hzid, String ckid) throws Exception {
        StringBuffer bf = new StringBuffer();
        for (String asnbh:set) {
            //判断查询同预期到货单下是否存在ASN单据号(同一货主仓库下不可重复)
            getASnCodeSFZ(asnbh, hzid, ckid, bf);
        }
        if (bf != null && !"".equals(bf) && bf.length() > 0) {
            throw new RuntimeException(bf.toString() + "数据库里调拨单号重复,导入失败");
        }
    }

    /**
     * 判断其他必填项,未填提示出来(导入 数据库去重必填项提示部分)
     * @param
     * @param list
     * @param gf
     */
    public void getBitian( Map<String, Object> list, StringBuffer gf) throws  Exception{
        if (list.get("hpbh") != null && !"".equals(list.get("hpbh"))) {

        } else {
            gf.append("第" + list.get("num") + "行，表格中物料编码是必填项；");
        }
        if (list.get("hpmc") != null && !"".equals(list.get("hpmc"))) {

        } else {
            gf.append("第" + list.get("num") + "行，表格中物料名称是必填项；");
        }
        if (list.get("hppc")!= null && !"".equals(list.get("hppc"))) {

        } else {
            gf.append("第" + list.get("num") + "行，表格中批次是必填项；");
        }
        if (list.get("scrq") != null && !"".equals(list.get("scrq"))) {

        } else {
            gf.append("第" + list.get("num") + "行，表格中生产日期是必填项；");
        }
        if (list.get("sxrq") != null && !"".equals(list.get("sxrq"))) {
        } else {
            gf.append("第" + list.get("num") + "行，表格中到期日期是必填项；");
        }
        if (list.get("asnbh") != null && !"".equals(list.get("asnbh"))) {
        } else {
            gf.append("第" + list.get("num") + "行，表格中调拨单单号是必填项；");
        }
        if (list.get("yqsl") != null && !"".equals(list.get("yqsl"))) {
        } else {
            gf.append("第" + list.get("num") + "行，表格中数量是必填项；");
        }
    }

    /**
     * 数据库去重(查询同预约收货单下是否存在ASN单据号(同一货主不可重复),以及若asn单存在,其下有无相应的预约单号)
     * @param asnbh
     * @param hzid
     * @param ckid
     * @param bf
     */
    public void getASnCodeSFZ(String asnbh, String hzid, String ckid, StringBuffer bf) throws Exception {
        // 判断查询同预期到货单下是否存在ASN单据号(同一货主仓库下不可重复),
        Integer e = dao.getCountByASN(hzid,asnbh, ckid);
        if (e > 0) {
            bf.append( "调拨单单号:" + asnbh);
        }
    }
}
